package com.mbengue.corp.artisan.vue;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableModel;

import com.mbengue.corp.artisan.controleur.Controleur;
import com.mbengue.corp.artisan.modele.Article;
import com.mbengue.corp.artisan.modele.Client;
import com.mbengue.corp.artisan.utils.ArticlePdfExporteur;
import com.mbengue.corp.artisan.utils.ClientPdfExporteur;
import com.mbengue.corp.artisan.utils.FeuillePdfExporteur;
import com.mbengue.corp.artisan.utils.Outil;
import com.mbengue.corp.artisan.utils.TypeComposant;
import com.mbengue.corp.artisan.vue.fenetre.AjoutArticle;
import com.mbengue.corp.artisan.vue.fenetre.AjoutClient;
import com.mbengue.corp.artisan.vue.fenetre.Chercher;
import com.mbengue.corp.artisan.vue.fenetre.ChercherFeuille;
import com.mbengue.corp.artisan.vue.fenetre.ChoixArticle;
import com.mbengue.corp.artisan.vue.fenetre.ChoixClient;
import com.mbengue.corp.artisan.vue.fenetre.Modifier;
import com.mbengue.corp.artisan.vue.menu.Menu;
import com.mbengue.corp.artisan.vue.outil.BarOutil;
import com.mbengue.corp.artisan.vue.outil.CelluleNoEditable;
import com.mbengue.corp.artisan.vue.tableau.Feuille;

public class MainView extends JFrame {
  private static final long serialVersionUID = 1878896657662902044L;
  private final Menu barDeMenu;
  private final BarOutil barOutil;
  private final Controleur controleur;
  @SuppressWarnings("rawtypes")
  private final Map<String, List> donnees;
  private TypeComposant composantCourant;
  private boolean estSauver = true;
  private boolean estVisualiseur = false;
  private boolean estRechercher = false;
  private Client client;
  private com.mbengue.corp.artisan.modele.Feuille feuille;
  private JTable tableau;
  private List<Article> tempDonneesFeuille;
  private boolean supprimerDonneesFeuille;

  @SuppressWarnings("rawtypes")
  public MainView(Controleur controleur) {
    super("L'Editeur");
    this.setSize(400, 400);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.controleur = controleur;
    this.barDeMenu = new Menu();
    this.barOutil = new BarOutil();
    this.donnees = new HashMap<String, List>(5);

    this.setJMenuBar(barDeMenu);
    this.ajouterComposant(barOutil, BorderLayout.NORTH);
    this.ajouterEcouterBarMenu();
    this.ajouterEcouteurBarOutil();
    this.setVisible(true);
  }

  private void ajouterEcouterBarMenu() {
    this.ajouterEcouteurBarMenuFichier();
    this.ajouterEcouteurBarMenuVisualiser();
    this.ajouterEcouteurBarMenuRechercher();
  }

  private void ajouterEcouteurBarMenuFichier() {
    ActionListener ajoutFacture = this.creerEcouteurNouvelleFeuille("Facture");
    this.barDeMenu.getFichier().getFacture().addActionListener(ajoutFacture);

    ActionListener ajoutDevis = this.creerEcouteurNouvelleFeuille("Devis");
    this.barDeMenu.getFichier().getDevis().addActionListener(ajoutDevis);

    ActionListener ajoutClient = this.creerEcouteurNouveauClient();
    this.barDeMenu.getFichier().getClient().addActionListener(ajoutClient);

    ActionListener ajoutArticle = this.creerEcouteurNouvelArticle();
    this.barDeMenu.getFichier().getArticle().addActionListener(ajoutArticle);

    ActionListener save = this.creerEcouteurSauver();
    this.barDeMenu.getFichier().getEnregistrer().addActionListener(save);

    ActionListener quitter = this.creerEcouteurQuitter();
    this.barDeMenu.getFichier().getQuitter().addActionListener(quitter);

    ActionListener ecouteurImprimer = this.creerEcouteurExporterOuImprimer();
    this.barDeMenu.getFichier().getImprimer().addActionListener(ecouteurImprimer);
  }

  private void ajouterEcouteurBarMenuVisualiser() {
    ActionListener voirFactures = this.creerEcouteurVoirFactures();
    this.barDeMenu.getVisualiser().getFacture().addActionListener(voirFactures);

    ActionListener voirDevis = this.creerEcouteurVoirDevis();
    this.barDeMenu.getVisualiser().getDevis().addActionListener(voirDevis);

    ActionListener voirArticle = this.creerEcouteurVoirArticle();
    this.barDeMenu.getVisualiser().getArticle().addActionListener(voirArticle);

    ActionListener voirClient = this.creerEcouteurVoirClient();
    this.barDeMenu.getVisualiser().getClient().addActionListener(voirClient);
  }

  private void ajouterEcouteurBarMenuRechercher() {
    ActionListener ecouteurClient = this.creerEcouteurRechercherClient();
    this.barDeMenu.getRechercher().getClient().addActionListener(ecouteurClient);

    ActionListener ecouteurArticle = this.creerEcouteurRechercherArticle();
    this.barDeMenu.getRechercher().getArticle().addActionListener(ecouteurArticle);

    ActionListener ecouteurFeuilleParDate = this.creerEcouteurRechercherFeuilleParDate();
    this.barDeMenu.getRechercher().getParDate().addActionListener(ecouteurFeuilleParDate);

    ActionListener ecouteurFeuilleParClient = this.creerEcouteurRechercherFeuilleParClient();
    this.barDeMenu.getRechercher().getParClient().addActionListener(ecouteurFeuilleParClient);

    ActionListener ecouteurFeuilleParNumero = this.creerEcouteurRechercherFeuilleParNumero();
    this.barDeMenu.getRechercher().getParNumero().addActionListener(ecouteurFeuilleParNumero);
  }

  private void ajouterEcouteurBarOutil() {
    // Bouton Ajouter
    ActionListener ecouteurAjout = this.creerEcouteurAjouter();
    this.barOutil.getAjouter().addActionListener(ecouteurAjout);

    // Bouton Valider
    ActionListener ecouteurSauver = this.creerEcouteurSauver();
    this.barOutil.getEnregistrer().addActionListener(ecouteurSauver);

    // Bouton Modifier
    ActionListener ecouteurModifier = this.creerEcouteurModifier();
    this.barOutil.getModifier().addActionListener(ecouteurModifier);

    // Bouton Supprimer
    ActionListener ecouteurSupprimer = this.creerEcouteurSupprimer();
    this.barOutil.getSupprimer().addActionListener(ecouteurSupprimer);

    // Bouton Assigner Client
    ActionListener assignerClient = this.creerEcouteurAssignerClient();
    this.barOutil.getClient().addActionListener(assignerClient);

    ActionListener ecouteurExporter = this.creerEcouteurExporterOuImprimer();
    this.barOutil.getExporter().addActionListener(ecouteurExporter);
  }

  private void annulerFeuilleClientEtTableau() {
    this.feuille = null;
    this.client = null;
    this.tableau = null;
    this.tempDonneesFeuille = null;
  }

  private void infoFeuille(String clientFeuille, String montantFeuille) {
    JLabel nomClient = new JLabel("Client:");
    JTextField valeurClient = new JTextField(clientFeuille, 10);
    valeurClient.setEditable(false);
    JLabel montant = new JLabel("Montant TTC: ");
    JTextField montantTTC = new JTextField(montantFeuille, 10);
    montantTTC.setEditable(false);
    JPanel panneau = new JPanel();
    panneau.add(nomClient);
    panneau.add(valeurClient);
    panneau.add(montant);
    panneau.add(montantTTC);
    panneau.setVisible(true);
    this.add(panneau, BorderLayout.SOUTH);
  }

  @SuppressWarnings("rawtypes")
  private String montantFeuille() {
    List donneesFeuille = this.donnees.get(this.composantCourant.getNom());
    double montant = 0.0;
    for (Object obj : donneesFeuille) {
      Article article = (Article) obj;
      montant += article.getPrix() * (1 + article.getTva());
    }
    DecimalFormat twoDForm = new DecimalFormat("####.##");
    return twoDForm.format(montant);
  }

  private void creerVisualiseur(Object[][] aVisualiser, String[] enTete, TypeComposant composantEnCours) {
    if (getContentPane().getComponentCount() > 1) {
      nettoyerVue(1);
      if (getContentPane().getComponentCount() > 1) {
        nettoyerVue(1);
      }
    }

    this.composantCourant = composantEnCours;
    this.tableau = new JTable(aVisualiser, enTete);
    this.ajouterComposant(this.tableau, BorderLayout.CENTER);
    this.repaint();
    this.barOutil.desactiverBoutons();
    this.barOutil.getExporter().setEnabled(true);
    this.setVisible(true);
    this.estSauver = true;
  }

  @Override
  public void repaint() {
    super.repaint();
    this.setVisible(true);
  }

  private void nettoyerVue(int index) {
    this.getContentPane().remove(index);
  }

  private void ajouterComposant(Component composant, String layOut) {
    this.getContentPane().add(new JScrollPane(composant), layOut);
  }

  private void nouvelleFeuille(String nomFeuille) {
    annulerFeuilleClientEtTableau();
    composantCourant = (nomFeuille == TypeComposant.FACTURE.getNom() ? TypeComposant.FACTURE : TypeComposant.DEVIS);
    estRechercher = false;
    estVisualiseur = false;
    if (getContentPane().getComponentCount() > 1) {
      nettoyerVue(1);
    }
    ajouterComposant(new Feuille(composantCourant.getNom()), BorderLayout.CENTER);
    donnees.put(composantCourant.getNom(), new ArrayList<com.mbengue.corp.artisan.modele.Article>());
    barOutil.desactiverBoutons();
    barOutil.getAjouter().setEnabled(true);
    barDeMenu.getFichier().getEnregistrer().setEnabled(false);
    barDeMenu.getFichier().getImprimer().setEnabled(false);
    infoFeuille("aucun", "0.0");
    setVisible(true);
  }

  private String[][] creerChoixArticle(Object[] articles) {
    String[][] donneesA = new String[articles.length][2];
    for (int index = 0; index < articles.length; index++) {
      Article article = (Article) articles[index];
      donneesA[index] = new String[] { article.getCode(), article.getDesignation() };
    }
    return donneesA;
  }

  private boolean estFeuille(TypeComposant composant) {
    if (composant.equals(TypeComposant.FEUILLE)) {
      return true;
    } else if (composant.equals(TypeComposant.FACTURE)) {
      return true;
    } else if (composant.equals(TypeComposant.DEVIS)) {
      return true;
    }
    return false;
  }

  private void removeAll(List<Article> listA, List<Article> listB) {
    for (Article articleB : listB) {
      for (Article articleA : listA) {
        if (articleA.getCode().equals(articleB.getCode())) {
          listA.remove(articleA);
          break;
        }
      }
    }
  }

  private List<Article> difference(List<Article> listA, List<Article> listB) {
    List<Article> resultat;
    if (listA.size() > listB.size()) {
      resultat = new ArrayList<Article>(listA);
      removeAll(resultat, listB);
    } else {
      resultat = new ArrayList<Article>(listB);
      removeAll(resultat, listA);
    }

    return resultat;
  }

  @SuppressWarnings({ "rawtypes", "unchecked" })
  private boolean sauverDonneesEnCours() {
    if(this.client == null) {
      JOptionPane.showMessageDialog(null, "Vous devez d'abord assigner cette feuille à un client.", "Attention",
          JOptionPane.WARNING_MESSAGE);
      return false;
    }

    try {
      List donneesCourantes = this.donnees.get(this.composantCourant.getNom());
      if (feuille != null) {
        this.controleur.modifierFeuille(feuille, tempDonneesFeuille, !supprimerDonneesFeuille);
      } else {
        if (this.composantCourant.equals(TypeComposant.FACTURE)) {
          feuille = this.controleur.creerFacture(donneesCourantes, client);
        } else if (this.composantCourant.equals(TypeComposant.DEVIS)) {
          feuille = this.controleur.creerDevis(donneesCourantes, client);
        }
      }
      this.estSauver = true;
      JOptionPane.showMessageDialog(null, "La sauvegarde a été un succès.", "Information",
          JOptionPane.INFORMATION_MESSAGE);
      return true;
    } catch (Exception exc) {
      exc.printStackTrace();
      JOptionPane.showMessageDialog(null, "Un problème est survenu lors de la sauvegarde.", "Attention",
          JOptionPane.WARNING_MESSAGE);
      return false;
    }
  }

  private ActionListener creerEcouteurAjouter() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        if (estFeuille(composantCourant)) {
          ChoixArticle choixArticle = new ChoixArticle(controleur, null);
          choixArticle.getValider().addActionListener(
              creerEcouteurValiderChoixArticle(choixArticle, composantCourant, true));
        } else if (composantCourant.equals(TypeComposant.CLIENT)) {
          new AjoutClient(controleur);
          barOutil.desactiverBoutons();
          annulerFeuilleClientEtTableau();
        } else if (composantCourant.equals(TypeComposant.ARTICLE)) {
          new AjoutArticle(controleur);
          barOutil.desactiverBoutons();
          annulerFeuilleClientEtTableau();
        }
      }
    };
  }

  private ActionListener creerEcouteurSauver() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        sauverDonneesEnCours();
        barOutil.getClient().setEnabled(false);
        barOutil.getEnregistrer().setEnabled(false);
        barOutil.getExporter().setEnabled(true);
        barDeMenu.getFichier().getImprimer().setEnabled(true);
        barDeMenu.getFichier().getEnregistrer().setEnabled(false);
      }
    };
  }

  private ActionListener creerEcouteurQuitter() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        if (!estSauver) {
          int option = JOptionPane.showConfirmDialog(null, "Voulez-vous enregistrer avant de quitter ?",
              "Fermer L'Editeur", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
          if (option == JOptionPane.OK_OPTION) {
            if (sauverDonneesEnCours()) {
              dispose();
              setVisible(false);
            }
          } else if (option == JOptionPane.CANCEL_OPTION || option == JOptionPane.CLOSED_OPTION) {
            return;
          } else {
            dispose();
            setVisible(false);
          }
        } else {
          dispose();
          setVisible(false);
        }
      }
    };
  }

  private ActionListener creerEcouteurNouvelleFeuille(final String nomFeuille) {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        nouvelleFeuille(nomFeuille);
      }
    };
  }

  private ActionListener creerEcouteurAssignerClient() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        final ChoixClient choixClient = new ChoixClient(controleur);
        choixClient.getValider().addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e2) {
            int choix = choixClient.getTableau().getSelectedRow();
            if (choix < 0) {
              JOptionPane.showMessageDialog(null, "Vous devez choisir un client avant de valider !", "Attention",
                  JOptionPane.WARNING_MESSAGE);
            } else {
              String telephone = (String) choixClient.getTableau().getModel().getValueAt(choix, 2);
              client = controleur.trouverClientParNumero2Telephone(telephone);
              choixClient.setVisible(false);
              choixClient.dispose();
              barOutil.getEnregistrer().setEnabled(true);
              barOutil.getExporter().setEnabled(true);
              barOutil.getClient().setEnabled(false);
              barDeMenu.getFichier().getEnregistrer().setEnabled(true);
              barDeMenu.getFichier().getImprimer().setEnabled(true);
              infoFeuille(client.getNom() + " " + client.getPrenom(), montantFeuille());
              repaint();
            }
          }
        });
      }
    };
  }

  private ActionListener creerEcouteurExporterOuImprimer() {
    return new ActionListener() {
      @Override
      @SuppressWarnings({ "rawtypes", "unchecked" })
      public void actionPerformed(ActionEvent e) {
        List donneesCourantes = donnees.get(composantCourant.getNom());
        try {
          String nomFichier;
          Object[][] objets;
          if (estFeuille(composantCourant)) {
            String[] enTete;
            float[] largeurCol;
            int nbLigne;
            if (estVisualiseur || estRechercher) {
              feuille = null;
              tempDonneesFeuille = null;
              objets = Outil.tableauFeuille(donneesCourantes);
              enTete = FeuillePdfExporteur.ENTETE_TABLEAU;
              largeurCol = FeuillePdfExporteur.LARGEUR_COLONNES;
              nomFichier = composantCourant.getNom() + "s.pdf";
              nbLigne = objets != null ? objets.length : 0;
            } else {
              objets = Outil.tableauArticle(donneesCourantes);
              nomFichier = composantCourant.getNom() + feuille.getNumero() + ".pdf";
              nbLigne = objets.length > 20 ? objets.length : 20;
              enTete = ArticlePdfExporteur.ENTETE_TABLEAU;
              largeurCol = ArticlePdfExporteur.LARGEUR_COLONNES;
            }
            FeuillePdfExporteur feuillePdfExporteur = new FeuillePdfExporteur(feuille, nomFichier, nbLigne, true,
                estVisualiseur | estRechercher);
            feuillePdfExporteur.creerPdf(objets, enTete, largeurCol);
          } else if (composantCourant.equals(TypeComposant.CLIENT)) {
            objets = Outil.tableauClient(donneesCourantes);
            nomFichier = composantCourant.getNom() + "s.pdf";
            ClientPdfExporteur clientPdfExporteur = new ClientPdfExporteur(nomFichier, objets.length, false);
            clientPdfExporteur.creerPdf(objets, ClientPdfExporteur.ENTETE_TABLEAU, ClientPdfExporteur.LARGEUR_COLONNES);
          } else {
            objets = Outil.tableauArticle(donneesCourantes);
            nomFichier = composantCourant.getNom() + "s.pdf";
            ArticlePdfExporteur artPdfExporteur = new ArticlePdfExporteur(nomFichier, objets.length, true);
            artPdfExporteur.creerPdf(objets, ArticlePdfExporteur.ENTETE_TABLEAU, ArticlePdfExporteur.LARGEUR_COLONNES);
          }
          Outil.imprimer(nomFichier);
        } catch (Exception e1) {
          e1.printStackTrace();
          JOptionPane.showMessageDialog(null, "Une erreur est survenue lors de l'export !", "Erreur",
              JOptionPane.ERROR_MESSAGE);
        }
      }
    };
  }

  private ActionListener creerEcouteurNouveauClient() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estRechercher = false;
        estVisualiseur = false;
        if (getContentPane().getComponentCount() > 1) {
          nettoyerVue(1);
        }
        new AjoutClient(controleur);
        barOutil.desactiverBoutons();
      }
    };
  }

  private ActionListener creerEcouteurNouvelArticle() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estRechercher = false;
        estVisualiseur = false;
        if (getContentPane().getComponentCount() > 1) {
          nettoyerVue(1);
        }
        new AjoutArticle(controleur);
        barOutil.desactiverBoutons();
      }
    };
  }

  private ActionListener creerEcouteurValiderChoixArticle(final ChoixArticle choixArticle, final TypeComposant composant,
 final boolean ajouter) {
    return new ActionListener() {
      @Override
      @SuppressWarnings("unchecked")
      public void actionPerformed(ActionEvent e2) {
        TableModel model = choixArticle.getTableau().getModel();
        int nbLigne = choixArticle.getNbArticles();
        if (nbLigne > 0) {
          String[] table = new String[nbLigne];
          // Recuperation de tous les codes articles
          for (int index = 0; index < nbLigne; index++) {
            Object valeur = model.getValueAt(index, 0);
            if (valeur != null) {
              table[index] = (String) valeur;
            }
          }
          choixArticle.dispose();
          choixArticle.setVisible(false);
          List<Article> arts = controleur.tousLesArticles(table);
          // anciennes données
          List<Article> data;
          if (feuille != null) {
            data = controleur.tousLesArticlesD1Feuille(feuille);
          } else {
            data = donnees.get(composant.getNom());
          }
          if (ajouter) {
            arts.addAll(data);
          }
          donnees.put(composant.getNom(), arts);
          tempDonneesFeuille = difference(arts, data);
          supprimerDonneesFeuille = data.size() > arts.size();
          Feuille facture = new Feuille(composant.getNom());
          facture.ajouterDonnees(arts);
          facture.rechargerFeuille();
          if (getContentPane().getComponentCount() > 1) {
            nettoyerVue(1);
          }
          ajouterComposant(facture, BorderLayout.CENTER);
          barOutil.activerBoutons();
          String nomClient = "aucun";
          if (client != null) {
            barOutil.getClient().setEnabled(false);
            barOutil.getEnregistrer().setEnabled(true);
            barDeMenu.getFichier().getEnregistrer().setEnabled(true);
            nomClient = client.getNom() + " " + client.getPrenom();
          } else {
            barOutil.getEnregistrer().setEnabled(false);
          }
          barOutil.getExporter().setEnabled(false);
          infoFeuille(nomClient, montantFeuille());
          repaint();
          estSauver = false;
        }
      }
    };
  }

  private void modifierOuSupprimerLigneFeuille(Object[] articles, boolean modifierOuSupprimer) {
    ChoixArticle artTableau = new ChoixArticle(this.controleur, creerChoixArticle(articles));
    if (modifierOuSupprimer) {
      artTableau.getNouvelle().setEnabled(true);
    } else {
      artTableau.getNouvelle().setEnabled(false);
    }
    artTableau.getSupprimer().setEnabled(true);
    artTableau.getValider().setEnabled(true);
    artTableau.getValider().addActionListener(
        creerEcouteurValiderChoixArticle(artTableau, this.composantCourant, false));
    artTableau.setVisible(true);
    this.nettoyerVue(1);
  }

  private ActionListener creerEcouteurModifier() {
    return new ActionListener() {
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @Override
      public void actionPerformed(ActionEvent e) {
        final List donneesCourantes = donnees.get(composantCourant.getNom());
        if (!estRechercher && !estVisualiseur) {
          if (estFeuille(composantCourant)) {
            modifierOuSupprimerLigneFeuille(donneesCourantes.toArray(), true);
          }
        } else {
          final int index = tableau.getSelectedRow();
          if (index < 0) {
            JOptionPane.showMessageDialog(null, "Vous devez d'abord sélectionner une ligne !!!", "Attention",
                JOptionPane.WARNING_MESSAGE);
          } else {
            try {
              final Object object = donneesCourantes.get(index);
              final Modifier modifieur;
              if (composantCourant.equals(TypeComposant.CLIENT)) {
                modifieur = new Modifier("Modifier Client", Outil.EN_TETE_CLIENT,
                    new Object[][] { ((Client) object).toArray() });
                modifieur.getValider().addActionListener(new ActionListener() {
                  @Override
                  public void actionPerformed(ActionEvent e2) {
                    Client clt = new Client();
                    clt.setNom((String) modifieur.getTableau().getValueAt(0, 0));
                    clt.setPrenom((String) modifieur.getTableau().getValueAt(0, 1));
                    clt.setTelephone((String) modifieur.getTableau().getValueAt(0, 2));
                    clt.setAdresse((String) modifieur.getTableau().getValueAt(0, 3));
                    clt.setCodePostal((String) modifieur.getTableau().getValueAt(0, 4));
                    clt.setVille((String) modifieur.getTableau().getValueAt(0, 5));
                    clt.setClientId(((Client) object).getClientId());
                    clt.setFullName(clt.getNom() + "-" + clt.getPrenom());
                    donneesCourantes.set(index, controleur.modifierClient(clt));
                    modifieur.dispose();
                    modifieur.setVisible(false);
                    creerVisualiseur(Outil.tableauClient(donneesCourantes), Outil.EN_TETE_CLIENT, composantCourant);
                    barOutil.getExporter().setEnabled(false);
                    barOutil.getSupprimer().setEnabled(true);
                    barOutil.getModifier().setEnabled(true);
                  }
                });
              } else if (composantCourant.equals(TypeComposant.ARTICLE)) {
                modifieur = new Modifier("Modifier Article", Outil.EN_TETE_ARTICLE,
                    new Object[][] { ((Article) object).toArray() });
                modifieur.getTableau().getColumnModel().getColumn(0).setCellEditor(new CelluleNoEditable());
                modifieur.getValider().addActionListener(new ActionListener() {
                  @Override
                  public void actionPerformed(ActionEvent e2) {
                    Article article = new Article();
                    article.setCode((String) modifieur.getTableau().getValueAt(0, 0));
                    article.setDesignation((String) modifieur.getTableau().getValueAt(0, 1));
                    double prix, tva;
                    if (modifieur.getTableau().getValueAt(0, 2) instanceof Double) {
                      prix = (Double) modifieur.getTableau().getValueAt(0, 2);
                    } else {
                      prix = Double.parseDouble((String) modifieur.getTableau().getValueAt(0, 2));
                    }
                    if (modifieur.getTableau().getValueAt(0, 3) instanceof Double) {
                      tva = (Double) modifieur.getTableau().getValueAt(0, 3);
                    } else {
                      tva = Double.parseDouble((String) modifieur.getTableau().getValueAt(0, 3));
                    }
                    article.setPrix(prix);
                    article.setTva(tva);
                    donneesCourantes.set(index, controleur.modifierArticle(article));
                    modifieur.dispose();
                    modifieur.setVisible(false);
                    creerVisualiseur(Outil.tableauArticle(donneesCourantes), Outil.EN_TETE_ARTICLE, composantCourant);
                    barOutil.getExporter().setEnabled(false);
                    barOutil.getSupprimer().setEnabled(true);
                    barOutil.getModifier().setEnabled(true);
                  }
                });
              } else {
                feuille = (com.mbengue.corp.artisan.modele.Feuille) object;
                client = feuille.getClient();
                List<Article> articles = controleur.tousLesArticlesD1Feuille(feuille);
                modifierOuSupprimerLigneFeuille(articles.toArray(), true);
              }
            } catch (Exception e1) {
              e1.printStackTrace();
              JOptionPane.showMessageDialog(null, "Une erreur s'est produite lors de la modification."
                  + " Veuillez recommencer ou redémarrer l'application", "Erreur", JOptionPane.ERROR_MESSAGE);
            }
          }
        }
      }
    };
  }

  private ActionListener creerEcouteurSupprimer() {
    return new ActionListener() {
      @Override
      @SuppressWarnings({ "rawtypes", "unchecked" })
      public void actionPerformed(ActionEvent e) {
        List donneesCourantes = donnees.get(composantCourant.getNom());
        if (!estRechercher && !estVisualiseur) {
          if (estFeuille(composantCourant)) {
            modifierOuSupprimerLigneFeuille(donneesCourantes.toArray(), false);
          }
        } else {
          int index = tableau.getSelectedRow();
          if (index < 0) {
            JOptionPane.showMessageDialog(null, "Vous devez d'abord sélectionner une ligne !!!", "Attention",
                JOptionPane.WARNING_MESSAGE);
          } else {
            if (estFeuille(composantCourant)) {
              int option = JOptionPane.showConfirmDialog(null, "Voulez-vous vraiment supprimer cette feuille ?",
                  "Supprimer Feuille", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
              if (option == JOptionPane.OK_OPTION) {
                try {
                  controleur.supprimerFeuille((com.mbengue.corp.artisan.modele.Feuille) donneesCourantes.get(index));
                  donneesCourantes.remove(index);
                  creerVisualiseur(Outil.tableauFeuille(donneesCourantes), Outil.EN_TETE_FEUILLE, composantCourant);
                  barOutil.getExporter().setEnabled(false);
                  barOutil.getSupprimer().setEnabled(true);
                  barOutil.getModifier().setEnabled(true);
                } catch (Exception e1) {
                  e1.printStackTrace();
                  JOptionPane.showMessageDialog(null, "Une erreur s'est produite lors de la suppression."
                      + " Veuillez recommencer ou redémarrer l'application", "Erreur", JOptionPane.ERROR_MESSAGE);
                }
              } else if (option == JOptionPane.CANCEL_OPTION || option == JOptionPane.CLOSED_OPTION) {
                return;
              }
            } else if (composantCourant.equals(TypeComposant.CLIENT)) {
              int option = JOptionPane.showConfirmDialog(null, "Voulez-vous vraiment supprimer ce client ?"
                  + "\nLa suppression de ce client entraînera la suppression de toutes les feuilles éditées pour lui.",
                  "Supprimer Client", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
              if (option == JOptionPane.OK_OPTION) {
                try {
                  controleur.supprimerClient((Client) donneesCourantes.get(index));
                  donneesCourantes.remove(index);
                } catch (Exception e1) {
                  e1.printStackTrace();
                  JOptionPane.showMessageDialog(null, "Une erreur s'est produite lors de la suppression."
                      + " Veuillez recommencer ou redémarrer l'application", "Erreur", JOptionPane.ERROR_MESSAGE);
                } finally {
                  creerVisualiseur(Outil.tableauClient(donneesCourantes), Outil.EN_TETE_CLIENT, composantCourant);
                  barOutil.getExporter().setEnabled(false);
                  barOutil.getSupprimer().setEnabled(true);
                  barOutil.getModifier().setEnabled(true);
                }
              } else if (option == JOptionPane.CANCEL_OPTION || option == JOptionPane.CLOSED_OPTION) {
                return;
              }
            } else if (composantCourant.equals(TypeComposant.ARTICLE)) {
              int option = JOptionPane.showConfirmDialog(null, "Voulez-vous vraiment supprimer cet article ?"
                  + "\nLa suppression de cet article entraînera la mise à jour de toutes "
                  + "les feuilles dans lesquelles il est présent. Et s'il est le dernier article de la feuille,"
                  + " cette dernière est alors supprimée à son tour ...", "Supprimer Client",
                  JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
              if (option == JOptionPane.OK_OPTION) {
                try {
                  controleur.supprimerArticle((Article) donneesCourantes.get(index));
                  donneesCourantes.remove(index);
                } catch (Exception e1) {
                  e1.printStackTrace();
                  JOptionPane.showMessageDialog(null, "Une erreur s'est produite lors de la suppression."
                      + " Veuillez recommencer ou redémarrer l'application", "Erreur", JOptionPane.ERROR_MESSAGE);
                } finally {
                  creerVisualiseur(Outil.tableauArticle(donneesCourantes), Outil.EN_TETE_ARTICLE, composantCourant);
                  barOutil.getExporter().setEnabled(false);
                  barOutil.getSupprimer().setEnabled(true);
                  barOutil.getModifier().setEnabled(true);
                }
              } else if (option == JOptionPane.CANCEL_OPTION || option == JOptionPane.CLOSED_OPTION) {
                return;
              }
            }
          }
        }
      }
    };
  }

  private ActionListener creerEcouteurVoirFactures() {
    return new ActionListener() {
      @SuppressWarnings({ "rawtypes", "unchecked" })
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estVisualiseur = true;
        estRechercher = false;
        composantCourant = TypeComposant.FACTURE;
        List factures = controleur.toutesLesFactures();
        donnees.put(composantCourant.getNom(), factures);
        creerVisualiseur(Outil.tableauFeuille(factures), Outil.EN_TETE_FEUILLE, TypeComposant.FACTURE);

        barOutil.getExporter().setEnabled(false);
        if (factures != null && factures.size() > 0) {
          barOutil.activerEditeur();
          barOutil.getAjouter().setEnabled(false);
        }
        barDeMenu.getFichier().getImprimer().setEnabled(true);
      }
    };
  }

  private ActionListener creerEcouteurVoirDevis() {
    return new ActionListener() {
      @Override
      @SuppressWarnings({ "rawtypes", "unchecked" })
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estVisualiseur = true;
        estRechercher = false;
        composantCourant = TypeComposant.DEVIS;
        List devis = controleur.tousLesDevis();
        donnees.put(composantCourant.getNom(), devis);
        creerVisualiseur(Outil.tableauFeuille(devis), Outil.EN_TETE_FEUILLE, TypeComposant.DEVIS);

        barOutil.getExporter().setEnabled(false);
        if (devis != null && devis.size() > 0) {
          barOutil.activerEditeur();
          barOutil.getAjouter().setEnabled(false);
        }
        barDeMenu.getFichier().getImprimer().setEnabled(true);
      }
    };
  }

  private ActionListener creerEcouteurVoirArticle() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estVisualiseur = true;
        estRechercher = false;
        composantCourant = TypeComposant.ARTICLE;
        List<Article> articles = controleur.tousLesArticles();
        donnees.put(composantCourant.getNom(), articles);
        creerVisualiseur(Outil.tableauArticle(articles), Outil.EN_TETE_ARTICLE, TypeComposant.ARTICLE);

        barOutil.getExporter().setEnabled(false);
        if (articles != null && articles.size() > 0) {
          barOutil.activerEditeur();
        }
        barDeMenu.getFichier().getImprimer().setEnabled(true);
      }
    };
  }

  private ActionListener creerEcouteurVoirClient() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        estVisualiseur = true;
        estRechercher = false;
        composantCourant = TypeComposant.CLIENT;
        List<Client> clients = controleur.tousLesClients();
        donnees.put(composantCourant.getNom(), clients);
        creerVisualiseur(Outil.tableauClient(clients), Outil.EN_TETE_CLIENT, TypeComposant.CLIENT);

        barOutil.getExporter().setEnabled(false);
        if (clients != null && clients.size() > 0) {
          barOutil.activerEditeur();
        }
        barDeMenu.getFichier().getImprimer().setEnabled(true);
      }
    };
  }

  private ActionListener creerEcouteurRechercherClient() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        final Chercher chClient = new Chercher("Rechercher Client", "Saississez un nom ou prenom de client !!!");
        chClient.getRechercher().addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e2) {
            String texte = chClient.getTexte().getText();
            if (texte == null || texte.equals("")) {
              JOptionPane.showMessageDialog(null, "Vous devez spécifier un nom ou prénom.", "Attention",
                  JOptionPane.WARNING_MESSAGE);
            } else {
              composantCourant = TypeComposant.CLIENT;
              List<Client> clients = controleur.trouverClientNomOuPrenom(texte);
              creerVisualiseur(Outil.tableauClient(clients), Outil.EN_TETE_CLIENT, TypeComposant.CLIENT);
              donnees.put(composantCourant.getNom(), clients);
              chClient.dispose();
              chClient.setVisible(false);

              barOutil.getExporter().setEnabled(false);
              if (clients != null && clients.size() > 0) {
                barOutil.activerEditeur();
              }
              estRechercher = true;
              estVisualiseur = false;
            }
          }
        });
      }
    };
  }

  private ActionListener creerEcouteurRechercherArticle() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        final Chercher chArticle = new Chercher("Rechercher Article",
            "Saississez le code ou partie du code de l'article!!!");
        chArticle.getRechercher().addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e2) {
            String texte = chArticle.getTexte().getText();
            if (texte == null || texte.equals("")) {
              JOptionPane.showMessageDialog(null, "Vous devez spécifier le code ou partie du code d'un article.",
                  "Attention", JOptionPane.WARNING_MESSAGE);
            } else {
              composantCourant = TypeComposant.ARTICLE;
              List<Article> articles = controleur.trouverArticlesParCode(texte);
              creerVisualiseur(Outil.tableauArticle(articles), Outil.EN_TETE_ARTICLE, TypeComposant.ARTICLE);
              donnees.put(composantCourant.getNom(), articles);
              chArticle.dispose();
              chArticle.setVisible(false);

              barOutil.getExporter().setEnabled(false);
              if (articles != null && articles.size() > 0) {
                barOutil.activerEditeur();
              }
              estRechercher = true;
              estVisualiseur = false;
            }
          }
        });
      }
    };
  }

  private ActionListener creerEcouteurRechercherFeuilleParDate() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        final ChercherFeuille chFeuille = new ChercherFeuille("Date", controleur);
        chFeuille.getRechercher().addActionListener(new ActionListener() {
          @SuppressWarnings("unchecked")
          @Override
          public void actionPerformed(ActionEvent e2) {
            Date dateDebut = chFeuille.getDateDebut().getDate();
            Date dateFin = chFeuille.getDateFin().getDate();
            if (dateDebut == null && dateFin == null) {
              JOptionPane.showMessageDialog(null, "Vous devez choisir au moins une date.", "Attention",
                  JOptionPane.WARNING_MESSAGE);
            } else {
              composantCourant = TypeComposant.FEUILLE;
              String type = (String) chFeuille.getTypeFeuille().getSelectedItem();
              List<com.mbengue.corp.artisan.modele.Feuille> feuilles = controleur.trouverFeuilleParDates(type,
                  dateDebut, dateFin);
              creerVisualiseur(Outil.tableauFeuille(feuilles), Outil.EN_TETE_FEUILLE, TypeComposant.valeurDe(type));
              donnees.put(composantCourant.getNom(), feuilles);
              chFeuille.dispose();
              chFeuille.setVisible(false);

              barOutil.getExporter().setEnabled(false);
              if (feuilles != null && feuilles.size() > 0) {
                barOutil.getModifier().setEnabled(true);
                barOutil.getSupprimer().setEnabled(true);
                barOutil.getExporter().setEnabled(true);
              }
              barDeMenu.getFichier().getImprimer().setEnabled(true);
              estRechercher = true;
              estVisualiseur = false;
            }
          }
        });
      }
    };
  }

  private ActionListener creerEcouteurRechercherFeuilleParClient() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        final ChercherFeuille chFeuille = new ChercherFeuille("Client", controleur);
        chFeuille.getRechercher().addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e2) {
            composantCourant = TypeComposant.FEUILLE;
            String type = (String) chFeuille.getTypeFeuille().getSelectedItem();
            String[] nomClient = ((String) chFeuille.getClients().getSelectedItem()).split("-");
            List<com.mbengue.corp.artisan.modele.Feuille> feuilles = controleur.trouverFeuillesParClient(nomClient[0],
                nomClient[1]);
            creerVisualiseur(Outil.tableauFeuille(feuilles), Outil.EN_TETE_FEUILLE, TypeComposant.valeurDe(type));
            donnees.put(composantCourant.getNom(), feuilles);
            chFeuille.dispose();
            chFeuille.setVisible(false);

            barOutil.getExporter().setEnabled(false);
            if (feuilles != null && feuilles.size() > 0) {
              barOutil.getModifier().setEnabled(true);
              barOutil.getSupprimer().setEnabled(true);
              barOutil.getExporter().setEnabled(true);
            }
            barDeMenu.getFichier().getImprimer().setEnabled(true);
            estRechercher = true;
            estVisualiseur = false;
          }
        });
      }
    };
  }

  private ActionListener creerEcouteurRechercherFeuilleParNumero() {
    return new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        annulerFeuilleClientEtTableau();
        final ChercherFeuille chFeuille = new ChercherFeuille("Numero", controleur);
        chFeuille.getRechercher().addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e2) {
            String numero = chFeuille.getNumero().getText();
            if (numero == null || numero.equals("")) {
              JOptionPane.showMessageDialog(null, "Vous devez saisir un numéro (ou partie d'un numéro) de feuille.",
                  "Attention", JOptionPane.WARNING_MESSAGE);
            } else {
              composantCourant = TypeComposant.FEUILLE;
              String type = (String) chFeuille.getTypeFeuille().getSelectedItem();
              List<com.mbengue.corp.artisan.modele.Feuille> feuilles = controleur
                  .trouverFeuillesParNumero(type, numero);
              creerVisualiseur(Outil.tableauFeuille(feuilles), Outil.EN_TETE_FEUILLE, TypeComposant.valeurDe(type));
              donnees.put(composantCourant.getNom(), feuilles);
              chFeuille.dispose();
              chFeuille.setVisible(false);

              barOutil.getExporter().setEnabled(false);
              if (feuilles != null && feuilles.size() > 0) {
                barOutil.getModifier().setEnabled(true);
                barOutil.getSupprimer().setEnabled(true);
                barOutil.getExporter().setEnabled(true);
              }
              barDeMenu.getFichier().getImprimer().setEnabled(true);
              estRechercher = true;
              estVisualiseur = false;
            }
          }
        });
      }
    };
  }
}
